import axios from "axios";
import router from "@/router";
import { getToken, removeToken } from "./token";
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from "axios";
import { ElMessageBox, ElMessage } from "element-plus";

const TOKEN_HEADER_NAME = "Authorization";
class Request {
    // axios 实例
    instance: AxiosInstance;

    constructor(config: AxiosRequestConfig) {
        this.instance = axios.create(config);
        /* 跳转到登录页面 */
        const goLogin = function (from?: string) {
            removeToken();

            //location.replace(`${process.env.VUE_APP_PATH}/#/login`);
            router.replace({
                path: "/login",
                query: from ? { from } : undefined,
            });
        };
        this.instance.interceptors.request.use(
            (res: AxiosRequestConfig) => {
                console.log("全局请求拦截器");
                // 添加token到header
                const token = getToken();
                if (token && config.headers) {
                    config.headers[TOKEN_HEADER_NAME] = "Bearer " + token;
                }

                return res;
            },
            (err) => err
        );
        this.instance.interceptors.response.use(
            // 因为我们接口的数据都在res.data下，所以我们直接返回res.data
            (res: AxiosResponse) => {
                const { data, config } = res;
                const { code, message } = data;
                if (code !== 200) {
                    //向控制台输出错误
                    console.warn(`${config.url}:${code}, ${message}`);

                    if (code === 401) {
                        const currentPath = router.currentRoute.value.path;
                        if (currentPath === "/") {
                            goLogin();
                        } else {
                            ElMessageBox.confirm("登录状态已过期, 请退出重新登录!", "系统提示", {
                                icon: "warning",
                            }).then(() => {
                                goLogin(currentPath);
                            });
                        }
                        return Promise.reject(message);
                    } else if (code === 403 || code === 400) {
                        ElMessage.error({
                            message,
                        });
                        return Promise.reject(data);
                    } else if (code === 500) {
                        ElMessage.error({
                            message: "系统异常，请联系管理员",
                        });
                    } else {
                        return Promise.reject(message);
                    }
                }

                return data.data;
            },
            (err) => {
                let { message } = err;

                if (message === "Network Error") {
                    message = "后端接口连接异常";
                }
                if (message.includes("timeout")) {
                    message = "后端接口请求超时";
                }
                if (message.includes("Request failed with status code")) {
                    const code = message.substr(message.length - 3);
                    message = "后端接口" + code + "异常";
                }

                return Promise.reject(err);
            }
        );
    }
    request(config: AxiosRequestConfig) {
        return this.instance.request(config);
    }
}

export default Request;
